<template>
  <div class="views" id="views" @touchmove.prevent @mousewheel.prevent>
    <div id="containerJxl" class="container"></div>
  </div>
</template>

<script>
import * as THREE from 'three/build/three.module'
import { ThreeJsUtil } from '@/assets/ThreeJsUtil/ThreeJsUtil'
import { MqttUtil } from '@/utils/MqttUtil'

const threeApp = new ThreeJsUtil()
export default {
  props: ['home'],
  data () {
    return {
      params: {
        methods: {
          animation: false,
          renderer: true,
          light: true,
          controls: true,
          TWEEN: true,
          postprocessing: true,
          statement: true
        },
        events: {
          windowResize: true
        },
        params: {
          containerId: 'containerJxl',
          renderer: [
            'WebGLRenderer'
          ],
          controls: [
            'OrbitControls'
          ],
          rendererParams: {
            antialias: true
          },
          postprocessing: [
            'OutlinePass',
            // 'UnrealBloomPass'
          ]
        }
      },
      topics: {
        pcj: `${this.$route.path}_position-controls-json`,
        soj: `${this.$route.path}_select-objName-json`,
        poj: `${this.$route.path}_perform-objName-json`
      },
      routerName: this.$route.name
    }
  },

  created() {
    console.log(threeApp);

  },
  mounted () {
    this.home.loading()
    /**
     * 初始化场景
     */
    threeApp.init(this.params, (scene, camera, renderer) => {
      // 添加天空盒
      // scene.background = new THREE.CubeTextureLoader()
      //   .setPath('static/model/img/skybox/')
      //   .load(['right.png', 'left.png', 'top.png', 'bottom.png', 'back.png', 'front.png']) // 右左上下后前
      // scene.background = new THREE.CubeTextureLoader()
      //   .setPath('static/model/img/skybox2/')
      //   .load(['RT.jpg', 'LF.jpg', 'UP.jpg', 'DN.jpg', 'BK.jpg', 'FR.jpg']) // 右左上下后前
      threeApp.addSky()

      // 重设相机初始位置
      camera.position.set(-16000, 4800, 16000)

      threeApp.orbitControls.autoRotate = false

      // // 设置辉光参数
      // threeApp.unrealBloomPass.threshold = 0
      // threeApp.unrealBloomPass.strength = 0.5
      // threeApp.unrealBloomPass.radius = 0
    })

    threeApp.addModel({
      url: 'static/model/fbx/torch/jxl.FBX',
      type: 'fbx',
      name: 'jxl'
    }, (obj) => {
      obj.scale.set(0.05, 0.05, 0.05)
      this.home.loadOver()
      // 相机飞行
      if (this.home.mqttForm.status !== 'sub' || !this.mqtt) {
        threeApp.flyTo({
          position: [8000, 2400, 0],
          controls: [0, 0, 0],
          duration: 3000
        })
      }

      // 添加双击事件
      threeApp.addOn(threeApp.scene, 'dblclick', (objList) => {
        const obj = objList[0].object

        // console.log(obj.parent.name)
        this.performEvent(obj)
        // console.log(`双击点引出的射线拾取到了${objList.length}个Mesh对象\n
        //   其中距离相机最近的Mesh对象所在组的名字为${group.name}\n
        //   该组中心点坐标为(${group.position.x},${group.position.y},${group.position.z})\n
        //   双击点与该组交点为(${objList[0].point.x},${objList[0].point.y},${objList[0].point.z})\n
        //   相机与该组中心点相距${objList[0].distance}`)
      }, 'dblclick_jxl', {
        recursive: true
      })

      // 添加鼠标移动事件
      threeApp.addOn(threeApp.scene, 'mousemove', (objList) => {
        const obj = objList[0].object

        this.selectEvent(obj)
        // threeApp.outlinePass.selectedObjects = [group]
      }, 'mousemove_jxl', {
        recursive: true
      }, () => {
        threeApp.outlinePass.selectedObjects = []
        this.curentGroupName = null
        this.mqttPubSelectObjName('null')
      })

      // 添加触摸事件
      threeApp.addOn(threeApp.scene, 'touchstart', (objList) => {
        const obj = objList[0].object
        const group = obj.parent

        if (group.name === this.curentGroupName) { // 判断为双击
          this.performEvent(obj)
        } else { // 判断为单击
          this.selectEvent(obj)
        }
      }, 'touchstart_jxl', { recursive: true }, () => {
        threeApp.outlinePass.selectedObjects = []
        this.curentGroupName = null
        this.mqttPubSelectObjName('null')
      })
    }, (progress) => {
      progress = parseInt((progress.loaded / progress.total) * 100)
      this.home.loadProgress(progress)
    })

    threeApp.animate(() => {
      this.mqttPubPositionControls()
    })
    this.mqttInit()
  },
  methods: {
    mqttInit () {
      if (this.home.mqttForm.status === 'sub') {
        if (this.mqtt) this.mqtt.client.end()
        this.mqtt = new MqttUtil(`mqtt://${this.home.mqttForm.url}`, { clientId: `${this.$route.name}_${this.home.mqttForm.status}` })
        this.mqtt.setSubTopic(this.topics.pcj)
        this.mqtt.setSubTopic(this.topics.soj)
        this.mqtt.setSubTopic(this.topics.poj)
        this.mqttSubInit()
        this.mqtt.subTopic(this.mqttSub)
      } else if (this.home.mqttForm.status === 'pub') {
        if (this.mqtt) this.mqtt.client.end()
        this.mqtt = new MqttUtil(`mqtt://${this.home.mqttForm.url}`, { clientId: `${this.$route.name}_${this.home.mqttForm.status}` })
      } else if (this.home.mqttForm.status === 'alone') {
        if (this.mqtt) this.mqtt.client.end()
        this.mqttSubDestroy()
      }
    },
    mqttSubInit () {
      threeApp.orbitControls.enabled = false
    },
    mqttSub (topic, message) {
      message = JSON.parse(message.toString())
      if (topic === this.topics.pcj && message) {
        threeApp.camera.position.set(...message.position)
        threeApp.camera.lookAt(...message.controls)
      } else if (topic === this.topics.soj && message) {
        if (message.objName !== 'null') {
          const obj = threeApp.scene.getObjectByName(message.objName)
          this.selectEvent(obj)
        } else {
          threeApp.outlinePass.selectedObjects = []
        }
      } else if (topic === this.topics.poj && message) {
        const obj = threeApp.scene.getObjectByName(message.objName)
        this.performEvent(obj)
      }
    },

    mqttSubDestroy () {
      threeApp.orbitControls.enabled = true
    },
    mqttPubPositionControls () {
      if (this.home.mqttForm.status !== 'pub' || !this.mqtt || this.$route.name !== this.routerName) return
      const controls = [threeApp.orbitControls.target.x, threeApp.orbitControls.target.y, threeApp.orbitControls.target.z]
      const position = [threeApp.camera.position.x, threeApp.camera.position.y, threeApp.camera.position.z]

      const message = JSON.stringify({
        position,
        controls
      })
      if (this.nextPCMessage === message) return
      this.nextPCMessage = message
      this.mqtt.pubTopic(this.topics.pcj, message)
    },
    mqttPubSelectObjName (objName) {
      if (this.home.mqttForm.status !== 'pub' || !this.mqtt || this.$route.name !== this.routerName) return
      const message = JSON.stringify({
        objName
      })
      this.mqtt.pubTopic(this.topics.soj, message)
    },
    mqttPubPerformObjName (objName) {
      if (this.home.mqttForm.status !== 'pub' || !this.mqtt || this.$route.name !== this.routerName) return
      const message = JSON.stringify({
        objName
      })
      this.mqtt.pubTopic(this.topics.poj, message)
    },
    selectEvent (obj) {
      const group = obj.parent
      switch (group.name) {
        case 'Group001': // 5楼
        case 'Group002': // 4楼
        case 'Group003': // 3楼
        case 'Group004': // 2楼
        case 'Group005': // 1楼
          threeApp.outlinePass.selectedObjects = [group]
          this.curentGroupName = group.name
          this.mqttPubSelectObjName(obj.name)
          break
        default:
          threeApp.outlinePass.selectedObjects = []
          this.curentGroupName = null
          this.mqttPubSelectObjName('null')
      }
    },
    performEvent (obj) {
      threeApp.outlinePass.selectedObjects = []
      this.curentGroupName = null
      this.mqttPubSelectObjName('null')
      return
      const group = obj.parent
      switch (group.name) {
        case 'Group001': // 5楼
          this.$router.push('jxl_floor5')
          this.home.tierChange('jxl_floor5')
          this.mqttPubPerformObjName(obj.name)
          break
        case 'Group002': // 4楼
          this.$router.push('jxl_floor34')
          this.home.tierChange('jxl_floor34')
          this.mqttPubPerformObjName(obj.name)
          break
        case 'Group003': // 3楼
          this.$router.push('jxl_floor34')
          this.home.tierChange('jxl_floor34')
          this.mqttPubPerformObjName(obj.name)
          break
        case 'Group004': // 2楼
          this.$router.push('jxl_floor2')
          this.home.tierChange('jxl_floor2')
          this.mqttPubPerformObjName(obj.name)
          break
        case 'Group005': // 1楼
          this.$router.push('jxl_floor1')
          this.home.tierChange('jxl_floor1')
          this.mqttPubPerformObjName(obj.name)
          break
      }
    }
  },
  beforeDestroy () {
    threeApp.rmOn('dblclick', 'dblclick_jxl')
    threeApp.rmOn('mousemove', 'mousemove_jxl')
    threeApp.rmOn('touchstart', 'touchstart_jxl')
    threeApp.destroy()
    if (this.mqtt) this.mqtt.client.end()
  }
}
</script>

<style scoped>
.views {
  height: 100%;
  width: 100%;
}

.container {
  height: 100%;
  width: 100%;
}
</style>
